﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace CommHelper
{
    public class NetHelper
    {
        /// <summary>
        /// 初始化赋值
        /// </summary>
        public readonly static string Ipstr = GetLocalIPv4();

        public readonly static uint Iptoint = IPToInt32(Ipstr);

        /// <summary>
        /// int转ip
        /// </summary>
        /// <param name="ipCode"></param>
        /// <returns></returns>
        public static string Int32ToIP(UInt32 ipCode)
        {
            byte a = (byte)((ipCode & 0xFF000000) >> 24);
            byte b = (byte)((ipCode & 0x00FF0000) >> 16);
            byte c = (byte)((ipCode & 0x0000FF00) >> 8);
            byte d = (byte)(ipCode & 0x000000FF);
            string ipStr = String.Format("{0}.{1}.{2}.{3}", a, b, c, d);
            return ipStr;
        }

        /// <summary>
        /// ip地址转int
        /// </summary>
        /// <param name="ipStr"></param>
        /// <returns></returns>
        public static UInt32 IPToInt32(string ipStr)
        {
            string[] ip = ipStr.Split('.');
            if (ip.Length >= 4)
            {
                uint ipCode = 0xFFFFFF00 | byte.Parse(ip[3]);
                ipCode = ipCode & 0xFFFF00FF | (uint.Parse(ip[2]) << 8);
                ipCode = ipCode & 0xFF00FFFF | (uint.Parse(ip[1]) << 16);
                ipCode = ipCode & 0x00FFFFFF | (uint.Parse(ip[0]) << 24);
                return ipCode;
            }
            return 0;
        }

        /// <summary>
        ///     获取本地IPV4地址
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIPv4()
        {
            try
            {
                string result = string.Empty;
                NetworkInterface[] fNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface adapter in fNetworkInterfaces)
                {
                    #region " 网卡类型 "

                    string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
                    RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
                    if (rk != null)
                    {
                        // 区分 PnpInstanceID
                        // 如果前面有 PCI 就是本机的真实网卡
                        // MediaSubType 为 01 则是常见网卡，02为无线网卡。                      int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
                        string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
                        if (fPnpInstanceID.Length > 3 && fPnpInstanceID.Substring(0, 3) == "PCI")
                        {
                            #region " 网卡信息 "

                            bool isGetPCI = false;
                            IPInterfaceProperties fIPInterfaceProperties = adapter.GetIPProperties();
                            UnicastIPAddressInformationCollection UnicastIPAddressInformationCollection = fIPInterfaceProperties.UnicastAddresses;
                            foreach (UnicastIPAddressInformation UnicastIPAddressInformation in UnicastIPAddressInformationCollection)
                            {
                                if (UnicastIPAddressInformation.Address.AddressFamily == AddressFamily.InterNetwork)
                                {
                                    result = UnicastIPAddressInformation.Address.ToString();
                                    isGetPCI = true;
                                    break;
                                }
                            }
                            if (isGetPCI) break;

                            #endregion " 网卡信息 "
                        }
                    }

                    #endregion " 网卡类型 "
                }
                return result;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }

        /// <summary>
        ///     获取MAC地址
        /// </summary>
        /// <returns></returns>
        public static string GetLocalNetCardMacAddress()
        {
            try
            {
                string result = string.Empty;
                NetworkInterface[] fNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface adapter in fNetworkInterfaces)
                {
                    #region " 网卡类型 "

                    string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
                    RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
                    if (rk != null)
                    {
                        // 区分 PnpInstanceID
                        // 如果前面有 PCI 就是本机的真实网卡
                        // MediaSubType 为 01 则是常见网卡，02为无线网卡。                      int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
                        string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
                        if (fPnpInstanceID.Length > 3 && fPnpInstanceID.Substring(0, 3) == "PCI")
                        {
                            var AddressBytes = adapter.GetPhysicalAddress().GetAddressBytes();
                            foreach (var temp in AddressBytes)
                            {
                                if (string.IsNullOrEmpty(result))
                                    result = string.Format("{0:X}", temp);
                                else
                                    result += "-" + string.Format("{0:X}", temp);
                            }
                            break;
                        }
                    }

                    #endregion " 网卡类型 "
                }
                return result;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }

        /// <summary>
        ///     是否为IP地址
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool IsIpAddress(string text)
        {
            IPAddress address;
            return IPAddress.TryParse(text, out address);
        }

        /// <summary>
        ///     是否为端口
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool IsPort(int port)
        {
            return ((port > 20) && (port < 0xffff));
        }

        /// <summary>
        ///     获取IP地址列表
        /// </summary>
        /// <returns></returns>
        public static List<string> GetIpAddressList()
        {
            var list = new List<string>();
            foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                string item = address.ToString();
                list.Add(item);
            }
            return list;
        }

        /// <summary>
        ///     获取IP地址列表
        /// </summary>
        /// <returns></returns>
        public static List<string> GetIpv4AddressList()
        {
            List<string> list = new List<string>();
            foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                string item = address.ToString();
                if (IsIPv4(item))
                {
                    list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        ///     远程连接
        /// </summary>
        /// <param name="ipAddress"></param>
        public static void RemoteConnection(string ipAddress)
        {
            try
            {
                var precess = new Process();
                precess.StartInfo.FileName = "mstsc.exe";
                precess.StartInfo.Arguments = "/v:" + ipAddress + " /f";
                precess.Start();
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        ///     判断两个Ip是否在同一个网络内
        /// </summary>
        /// <param name="maskAddress"></param>
        /// <param name="address1"></param>
        /// <param name="address2"></param>
        /// <returns></returns>
        public static bool InSameSubNet(string maskAddress, string address1, string address2)
        {
            return IPAddress.Parse(address1).Equals(IPAddress.Parse(address2));
        }

        /// <summary>
        ///     判断输入的字符串是否是表示一个IP地址
        /// </summary>
        /// <param name="input">被比较的字符串</param>
        /// <returns>是IP地址则为True</returns>
        public static bool IsIPv4(string input)
        {
            string[] IPs = input.Split('.');
            var regex = new Regex(@"^\d+$");
            for (int i = 0; i < IPs.Length; i++)
            {
                if (!regex.IsMatch(IPs[i]))
                {
                    return false;
                }
                if (Convert.ToUInt16(IPs[i]) > 255)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        ///     判断输入的字符串是否是合法的IPV6 地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsIPV6(string input)
        {
            string pattern = "";
            string temp = input;
            string[] strs = temp.Split(':');
            if (strs.Length > 8)
            {
                return false;
            }
            int count = GetStringCount(input, "::");
            if (count > 1)
            {
                return false;
            }
            else if (count == 0)
            {
                pattern = @"^([\da-f]{1,4}:){7}[\da-f]{1,4}$";

                var regex = new Regex(pattern);
                return regex.IsMatch(input);
            }
            else
            {
                pattern = @"^([\da-f]{1,4}:){0,5}::([\da-f]{1,4}:){0,5}[\da-f]{1,4}$";
                var regex1 = new Regex(pattern);
                return regex1.IsMatch(input);
            }
        }

        /// <summary>
        ///     判断字符串compare 在 input字符串中出现的次数
        /// </summary>
        /// <param name="input">源字符串</param>
        /// <param name="compare">用于比较的字符串</param>
        /// <returns>字符串compare 在 input字符串中出现的次数</returns>
        private static int GetStringCount(string input, string compare)
        {
            int index = input.IndexOf(compare);
            if (index != -1)
            {
                return 1 + GetStringCount(input.Substring(index + compare.Length), compare);
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 检测端口是否被暂用
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool IsPortInUse(int port)
        {
            bool inUse = false;

            System.Net.NetworkInformation.IPGlobalProperties ipProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
            List<IPEndPoint> allPorts = new List<IPEndPoint>();
            IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
            if (ipEndPoints != null && ipEndPoints.Length > 0)
                allPorts.AddRange(ipEndPoints);

            ipEndPoints = ipProperties.GetActiveUdpListeners();
            if (ipEndPoints != null && ipEndPoints.Length > 0)
                allPorts.AddRange(ipEndPoints);

            foreach (IPEndPoint endPoint in allPorts)
            {
                if (endPoint.Port == port)
                {
                    inUse = true;
                    break;
                }
            }

            return inUse;
        }

        /// <summary>
        /// 获取硬盘地址
        /// </summary>
        /// <returns></returns>
        public static string GetDiskID()
        {
            String HDid = string.Empty;
            try
            {
                ManagementClass cimobject = new ManagementClass("Win32_PhysicalMedia");
                ManagementObjectCollection moc = cimobject.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    HDid = mo.Properties["SerialNumber"].Value + "";
                    if (!string.IsNullOrEmpty(HDid))
                    {
                        break;
                    }
                }
                if (string.IsNullOrEmpty(HDid))
                {
                    HDid = GetNetCardMACAddress();
                }
            }
            catch (Exception ex)
            {
            }
            return HDid.Trim();
        }

        public static string GetNetCardMACAddress()
        {
            string NetCardMACAddress = string.Empty;
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> 'Microsoft'))");

                foreach (ManagementObject mo in searcher.Get())
                {
                    NetCardMACAddress = mo["MACAddress"] + "";
                    if (!string.IsNullOrEmpty(NetCardMACAddress))
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return NetCardMACAddress.Trim();
        }

        public static List<string> GetPrintList()
        {
            ManagementObjectCollection printers = new ManagementObjectSearcher("SELECT * FROM Win32_Printer").Get();
            List<string> liststr = new List<string>();
            try
            {
                if (printers != null)
                {
                    string protname = string.Empty;
                    foreach (ManagementObject printer in printers)
                    {
                        protname = printer.Properties["PortName"].Value + "";
                        if (!(string.IsNullOrEmpty(protname) || protname.ToLower().Contains("fax")
                            || protname.ToLower().Contains("reader") || protname.ToLower().Contains("xpsport")
                            || protname.ToLower().Contains("nul")))
                        {
                            liststr.Add(printer.Properties["Name"].Value + "");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return liststr;
        }
    }
}